package ar.com.ctrln.view.dashboard.administracion.liquidacion;

import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Button;
import org.zkoss.zul.Constraint;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Label;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Window;

import ar.com.ctrln.control.administracion.liquidaciones.RegistrarLiquidacion;
import ar.com.ctrln.persistence.model.cliente.Cliente;
import ar.com.ctrln.persistence.model.contratacion.DetalleContratacionInternet;
import ar.com.ctrln.persistence.model.liquidacion.Componente;
import ar.com.ctrln.persistence.model.liquidacion.ComponenteEgreso;
import ar.com.ctrln.persistence.model.liquidacion.ComponenteIngreso;
import ar.com.ctrln.persistence.model.liquidacion.DetalleLiquidacion;
import ar.com.ctrln.persistence.model.liquidacion.Liquidacion;
import ar.com.ctrln.persistence.model.servicios.internet.ServicioInternet;
import ar.com.ctrln.view.ui.comportamientoVentana.AbstractMinimizarVentana;

public class GenerarLiquidacionController extends AbstractMinimizarVentana {

	private static final long serialVersionUID = -3421878298493378895L;

	@WireVariable
	private RegistrarLiquidacion registrarLiquidacion;

	@Wire
	private Window wGenerarLiquidacion;

	@Wire
	private Listbox lbContrataciones;

	@Wire
	private Label lClienteSeleccionado;

	@Wire
	private Datebox fechaDesde;

	@Wire
	private Datebox fechaHasta;

	@Wire
	private Label lTotalIngreso;

	@Wire
	private Label lTotalEgreso;

	@Wire
	private Label lTotal;

	@Wire
	private Listbox lbDetalleLiquidacion;

	@Wire
	private Button btnGenerarLiquidacion;

	private ListModelList<DetalleContratacionInternet> modeloContratacion;
	private ListModelList<Componente> modeloComponente;

	private Cliente rCliente;

	private Liquidacion rLiquidacion;

	private DetalleLiquidacion detalle = new DetalleLiquidacion();

	Set<DetalleContratacionInternet> selecciones = new HashSet<DetalleContratacionInternet>();

	@Override
	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);
		modeloComponente = new ListModelList<Componente>();

		rCliente = (Cliente) this.getSelf().getParent().getAttribute("cliente");

		lClienteSeleccionado.setValue(rCliente.getRazonSocial());

		rLiquidacion = (Liquidacion) this.getSelf().getParent()
				.getAttribute("liquidacion");

		fechaDesde.setValue(rLiquidacion.getFechaDesde());

		fechaHasta.setValue(rLiquidacion.getFechaHasta());

		detalle = registrarLiquidacion.buscarDetalleLiquidacion(
				rLiquidacion.getMes(), rLiquidacion.getAnio(),
				rLiquidacion.getId(), rCliente.getId());

		if (detalle != null) {
			Clients.showNotification("Los conceptos de Liquidacion se encuentran abiertos y pendientes para facturar");
			modeloComponente.addAll(detalle.getComponentes());
			lTotalIngreso.setValue("Total Ingreso: $ "
					+ detalle.getTotalIngreso());
			lTotalEgreso
					.setValue("Total Egreso: $ " + detalle.getTotalEgreso());
			lTotal.setValue("Total a Pagar: $ " + detalle.getTotal());

		} else {
			detalle = new DetalleLiquidacion();
			detalle.setAnio(rLiquidacion.getAnio());
			detalle.setMes(rLiquidacion.getMes());
			detalle.setFechaDesde(rLiquidacion.getFechaDesde());
			detalle.setFechaHasta(rLiquidacion.getFechaHasta());
			detalle.setLiquidacion(rLiquidacion);
			detalle.setTotal(0);
			detalle.setTotalEgreso(0);
			detalle.setTotalIngreso(0);
			detalle.setCliente(rCliente);
			registrarLiquidacion.nuevo(detalle);

		}

		lbDetalleLiquidacion.setModel(modeloComponente);

		fechaHasta.setConstraint(new Constraint() {

			@Override
			public void validate(Component comp, Object value) {
				Date fin = (Date) value;

				if (fin.before(fechaDesde.getValue())) {

					Clients.showNotification("Modifique la fecha", fechaDesde);
					throw new WrongValueException(comp, "Error en fecha");
				}

			}
		});

		fechaDesde.addEventListener("onChange", new EventListener<Event>() {

			@Override
			public void onEvent(Event event) throws Exception {
				Date date = fechaDesde.getValue();

				Calendar calendar = Calendar.getInstance(Locale.getDefault());
				calendar.setTime(date);
				calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);

				fechaHasta.setValue(calendar.getTime());

			}
		});

		modeloContratacion = new ListModelList<DetalleContratacionInternet>();
		modeloContratacion.setMultiple(true);

		if (rCliente != null) {
			modeloContratacion.addAll(registrarLiquidacion
					.listarDetallesContratacionInternet(rCliente.getId()));

		}
		lbContrataciones.setMultiple(true);
		lbContrataciones.setCheckmark(true);
		lbContrataciones.setModel(modeloContratacion);
	}

	@Listen("onClick = #btnGenerarLiquidacion")
	public void onGenerarLiquidacion() {

		Set<Componente> componentes = new HashSet<Componente>();
		int cantidadAbonados = 0;
		double totalIngreso = 0;

		selecciones.addAll(modeloContratacion.getSelection());

		if (!selecciones.isEmpty()) {

			for (DetalleContratacionInternet seleccion : selecciones) {
				ComponenteIngreso ingreso = new ComponenteIngreso();

				ServicioInternet servicio = (ServicioInternet) seleccion
						.getServicio();
				ingreso.setServicio(servicio);
				ingreso.setNombre(" Servicio: "
						+ servicio.getNombre());
				ingreso.setObservacion("Total a pagar por Cliente "
						+ rCliente.getRazonSocial() + " por el Servicio "
						+ servicio.getNombre());
				ingreso.setFecha(new Date());
				ingreso.setDetalle(detalle);
				ingreso.setAbonados(seleccion.getCantidadUsuarios());
				ingreso.setTotal(servicio.getPrecio()
						* seleccion.getCantidadUsuarios());
				ingreso.setImporte(servicio.getPrecio());
				componentes.add(ingreso);

				ingreso.setSimbolo("$");

				ingreso.setDetalle(detalle);

				cantidadAbonados += ingreso.getAbonados();
				totalIngreso += ingreso.getTotal();

			}

			ComponenteEgreso compensacion = new ComponenteEgreso();
			compensacion.setNombre("Compensacion Internet");
			compensacion.setImporte(21.00);
			compensacion.setTotal(21 * cantidadAbonados);
			compensacion.setFecha(new Date());
			compensacion.setSimbolo("$");
			compensacion.setDetalle(detalle);
			compensacion.setValorNeg((-1) * compensacion.getTotal());
			componentes.add(compensacion);

			ComponenteEgreso comisiones = new ComponenteEgreso();
			comisiones.setImporte(15.00);
			comisiones.setNombre("Comisiones Venta");
			comisiones.setFecha(new Date());
			comisiones.setTotal(totalIngreso * (comisiones.getImporte() / 100));
			comisiones.setValorNeg(comisiones.getTotal() * -1);
			comisiones.setSimbolo("%");
			comisiones.setDetalle(detalle);

			componentes.add(comisiones);

			modeloComponente.clear();
			modeloComponente.addAll(componentes);

			detalle.setTotalIngreso(totalIngreso);

			detalle.setTotalEgreso((comisiones.getTotal() + compensacion
					.getTotal()));

			detalle.setTotal((totalIngreso - ((comisiones.getTotal() + compensacion
					.getTotal()))));

			lTotalIngreso.setValue("Total Ingreso: $ " + totalIngreso);
			lTotalEgreso.setValue("Total Egreso: $ "
					+ (comisiones.getTotal() + compensacion.getTotal()));
			lTotal.setValue("Total a Pagar: $ "
					+ (totalIngreso - ((comisiones.getTotal() + compensacion
							.getTotal()))));

			for (Componente componente : componentes) {
				registrarLiquidacion.nuevo(componente);

			}
			detalle.setComponentes(componentes);

			registrarLiquidacion.actualizarDetalle(detalle);
		}

	}
}